/**
 * class that implements the multiplication operand
 * 
 * @author Nadav Cohen, Matan Monitz
 *
 */
public class Multiplication implements Expression {
	
	private Expression leftExp=null;
	private Expression rightExp=null;
	/**
	 * a constructor method for multiplication
	 * @param exp1 object implementing the expression interface used for the left size of the multiplication
	 *  - must not be null
	 * @param exp2 object implementing the expression interface used for the right size of the multiplication
	 *  - must not be null
	 */
	public Multiplication(Expression exp1,Expression exp2)
	{
		
		if(exp1==null || exp2==null)
			throw new RuntimeException("Multiplication couldn't iniliaze - input uninitialzed!");
		this.leftExp=exp1;
		this.rightExp=exp2;
	}
	/**
	 * checks if the objects are the same by calling the equals method on both sides of the multiplication operand
	 */
	public boolean equals(Object other)
	{
		if(other != null)
			{
			if(other instanceof Multiplication)
				return (this.leftExp.equals(((Multiplication)other).leftExp) && this.rightExp.equals(((Multiplication)other).rightExp));
			}
		return false;
	}
	
	public String toString()
	{
		return "(" + leftExp.toString() + "*" + rightExp.toString() + ")"; 
	}
	
	public double evaluate(Assignments assignments) {
		if (assignments == null)
			throw new RuntimeException("invalid input array, assignments is null");
		return leftExp.evaluate(assignments)*rightExp.evaluate(assignments);
	}

	public Expression derivative(Variable var) {
		if(var == null)
			throw new RuntimeException("invalid input, Variable is null");
		//using the equivalent of (A*B)' = (A*B')+(B*A')
		return (new Addition(new Multiplication(leftExp,rightExp.derivative(var)),new Multiplication(leftExp.derivative(var),rightExp)));
		
	}

}
